#c #templates #compiler-errors #tuples #c 11
#c #шаблоны #ошибки компилятора #кортежи #c 11
Вопрос:
У меня есть следующий код:
class TR_AgentInfo : public tuple<
long long, //AgentId
string, //AgentIp
>
{
public:
TR_AgentInfo() {}
TR_AgentInfo(
const long longamp; AgentId,
const stringamp; AgentIp,
)
{
get<0>(*this) = AgentId;
get<1>(*this) = AgentIp;
}
long long getAgentId() const { return get<0>(*this); }
void setAgentId(const long longamp; AgentId) { get<0>(*this) = AgentId; }
string getAgentIp() const { return get<1>(*this); }
void setAgentIp(const stringamp; AgentIp) { get<1>(*this) = AgentIp; }
};
Теперь я хочу использовать этот код:
int count = tuple_size<TR_AgentInfo>::value;
но gcc выдает эту ошибку:
error: incomplete type std::tuple_size<TR_AgentInfo> used in nested name specifier
теперь , что я могу сделать ?
Комментарии:
1. В чем собственно проблема? Похоже, что размер кортежа всегда равен 2, так к чему эта гимнастика?
2. Я слишком упростил свой код! эти коды будут сгенерированы созданным мной TemplateGenerator, а затем будут использоваться в другой библиотеке шаблонов, которая является очень общей.
3. Почему вы не сохраняете размер кортежа как константу статического класса? Или введите кортеж, чтобы вы могли использовать его позже
std::tuple_size<MyClass::tuple_type>::value
?4. Я хочу, чтобы дочерний класс вел себя точно так же, как кортеж.
5. Если ваш класс завершен, тогда скажите
namespace std { template<> struct tuple_size<TR_AgentInfo> { static const size_t value = 2; }; }
. Добавление специализаций в пространство имен явно разрешено.
Ответ №1:
Если вы хотите, чтобы ваш единственный класс работал с std::tuple_size
, вы можете просто указать специализацию:
namespace std
{
template<> struct tuple_size<TR_AgentInfo>
{
static const size_t value = 2;
// alternatively, `tuple_size<tuple<long long, string>>::value`
// or even better, `tuple_size<TR_AgentInfo::tuple_type>::value`, #1
};
}
Вам явно разрешено добавлять специализации в пространство std
имен, именно для ситуаций, подобных вашей.
Если ваш фактический класс сам по себе шаблонный, вы можете просто заменить 2
его соответствующей конструкцией. Например, для предложения № 1 вы могли бы добавить typedef для tuple_type
своего класса. Есть много способов скинуть этот cat.
Ответ №2:
Если у вас есть экземпляр TR_AgentInfo
kicking around, вы можете использовать вычет типа шаблона функции, чтобы сделать его более удобным, например:
template <typename... T>
std::size_t get_tuple_size(std::tuple<T...> const amp;)
{
return sizeof...(T);
}
и позвонить
TR_AgentInfo info;
int count = get_tuple_size(info);
в противном случае вам нужно использовать правильное метапрограммирование, чтобы добраться до базового класса, но средства доступны.
Комментарии:
1. Я не хочу получать его в базовом классе. Мне нужно использовать tuple_size
2. Вы запрашиваете tuple_size класса, который не является кортежем. Базовый класс — это кортеж. Вы можете получить tuple_size этого базового класса. Или я что-то упускаю?
3. Я хочу получить tuple_size дочернего класса.
4.Как вы думаете, в чем разница? В каком смысле дочерний класс здесь отличается от кортежа базового класса? В конце концов, вы используете общедоступное наследование, чтобы явно выразить отношение IS-A, т. Е. Сказать, Что
TR_AgentInfo
это atuple<long long, string>
.